package com.yhsimon.prototype.deepclone;

import java.io.*;

public class DeepProtoType implements Serializable,Cloneable {
    public String name;
    public DeepCloneableTarget deepCloneableTarget;

    public DeepProtoType() {
    }

    @Override
    public String toString() {
        return "DeepProtoType{" +
                "name='" + name + '\'' +
                ", deepCloneableTarget=" + deepCloneableTarget.toString() +
                '}';
    }

    //深拷贝-方式1使用clone方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object deep=null;
        //这里完成对基本数据类型（属性）和String的克隆
        deep = super.clone();
        //对引用类型的属性，进行单独处理
        DeepProtoType deepProtoType= (DeepProtoType) deep;
        //有点像递归（套娃） 因为该引用对象的属性只包含基本数据类型
        deepProtoType.deepCloneableTarget= (DeepCloneableTarget) deepCloneableTarget.clone();
        return  deepProtoType;
    }

    //深拷贝-方式2 通过对象的序列化实现（推荐）
    public Object deepClone(){
        ByteArrayOutputStream bos=null;
        ObjectOutputStream oos=null;
        ByteArrayInputStream bis=null;
        ObjectInputStream ois=null;
        try {
            //序列化
            bos=new ByteArrayOutputStream();
            oos=new ObjectOutputStream(bos);
            oos.writeObject(this);//当前对象以对象流的方式输出

            //反序列化
            bis=new ByteArrayInputStream(bos.toByteArray());
            ois=new ObjectInputStream(bis);
            DeepProtoType copyObj= (DeepProtoType) ois.readObject();
            return copyObj;
        }catch (Exception e){
            System.out.println(e.getMessage());
            return null;
        }finally {
            try{
                if(bos!=null){
                    bos.close();
                }
                if(oos!=null){
                    oos.close();
                }
                if(bis!=null){
                    bis.close();
                }
                if(ois!=null){
                    ois.close();
                }
            }catch (Exception e){
                System.out.println(e.getMessage());
            }
        }
    }
}
